/**
 * @file time_utils.c
 * @brief 时间处理工具实现
 * @details 本文件实现了104协议的时间处理工具功能，包括系统时间与CP56Time2a格式
 *          的相互转换、时间验证、时间比较、时间格式化等核心功能。支持多种时间
 *          格式转换和验证，确保时间数据的准确性和一致性。
 * 
 * @author zyb
 * @date 2025-10-03
 * @version 1.0
 * 
 * @note CP56Time2a时间格式是104协议的标准时间格式，包含毫秒精度
 * @warning 时间转换需要考虑时区问题，建议使用UTC时间
 * 
 * @see time_utils.h
 * @see protocol_types.h
 * @see constants.h
 */

#define _XOPEN_SOURCE

#include "time_utils.h"
#include "../../../../../common/logs/include/logger.h"
#include <time.h>
#include <stdio.h>
#include <string.h>

// 定义模块名称
#define LOG_MODULE_NAME "TIME_UTILS"

/* ==================== 时间转换函数实现 ==================== */

/**
 * @brief 将系统时间转换为CP56Time2a格式
 * @details 将系统时间戳（time_t类型）转换为104协议标准的CP56Time2a时间格式。
 *          函数使用localtime()将系统时间转换为本地时间结构，然后提取各个时间
 *          字段并转换为CP56Time2a格式。年份相对于1992年计算。
 * 
 * @param system_time 系统时间戳（秒），从1970年1月1日开始计算
 * @param cp56time CP56Time2a时间结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 无效时间戳
 * 
 * @note 毫秒字段设置为0，因为系统时间精度限制
 * @warning 年份超出CP56Time2a范围时会返回错误
 * 
 * @see cp56time2a_t
 * @see CP56TIME2A_YEAR_BASE
 * @see CP56TIME2A_MAX_YEAR
 */
protocol_error_t system_time_to_cp56time2a(time_t system_time, cp56time2a_t* cp56time) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换系统时间到CP56Time2a格式: system_time=%ld, cp56time=%p", system_time, cp56time);
    
    if (cp56time == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "开始转换系统时间到CP56Time2a格式");
    struct tm* tm_info = localtime(&system_time);
    if (tm_info == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "localtime转换失败: system_time=%ld", system_time);
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "localtime转换成功: %04d-%02d-%02d %02d:%02d:%02d", 
              tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
              tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec);
    
    /* 设置年份（相对于1992年） */
    cp56time->year = tm_info->tm_year + 1900 - CP56TIME2A_YEAR_BASE;
    LOG_DEBUG(LOG_MODULE_NAME, "计算年份: %d - %d = %d", tm_info->tm_year + 1900, CP56TIME2A_YEAR_BASE, cp56time->year);
    if (cp56time->year > CP56TIME2A_MAX_YEAR) {
        LOG_ERROR(LOG_MODULE_NAME, "年份超出范围: %d > %d", cp56time->year, CP56TIME2A_MAX_YEAR);
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 设置月份 */
    cp56time->month = tm_info->tm_mon + 1;
    LOG_DEBUG(LOG_MODULE_NAME, "设置月份: %d", cp56time->month);
    
    /* 设置日期 */
    cp56time->day_of_month = tm_info->tm_mday;
    LOG_DEBUG(LOG_MODULE_NAME, "设置日期: %d", cp56time->day_of_month);
    
    /* 设置小时 */
    cp56time->hours = tm_info->tm_hour;
    LOG_DEBUG(LOG_MODULE_NAME, "设置小时: %d", cp56time->hours);
    
    /* 设置分钟 */
    cp56time->minutes = tm_info->tm_min;
    
    /* 设置秒 */
    cp56time->milliseconds = tm_info->tm_sec * 1000;
    
    /* 设置毫秒（系统时间精度限制，这里设为0） */
    /* cp56time->milliseconds already set above */
    
    return PROTOCOL_SUCCESS;
}

/**
 * @brief CP56Time2a时间戳转系统时间
 * @details 将CP56Time2a格式的时间戳转换为系统时间（time_t）。
 *          提供时间格式转换功能，用于协议时间与系统时间的互转。
 * 
 * @param cp56time CP56Time2a时间戳，不能为NULL
 * @param system_time 系统时间输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_TIMESTAMP: 无效时间戳
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 数据时间戳无效
 * 
 * @note 使用mktime进行时间转换
 * @warning 时间戳必须是有效的CP56Time2a格式
 * 
 * @see system_time_to_cp56time2a
 * @see validate_cp56time2a
 * @see mktime
 */
protocol_error_t cp56time2a_to_system_time(const cp56time2a_t* cp56time, time_t* system_time) {
    if (cp56time == NULL || system_time == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证时间戳 */
    protocol_error_t result = validate_cp56time2a(cp56time);
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    struct tm tm_info;
    memset(&tm_info, 0, sizeof(struct tm));
    
    /* 设置年份 */
    tm_info.tm_year = cp56time->year + CP56TIME2A_YEAR_BASE - 1900;
    
    /* 设置月份（tm_mon从0开始） */
    tm_info.tm_mon = cp56time->month - 1;
    
    /* 设置日期 */
    tm_info.tm_mday = cp56time->day_of_month;
    
    /* 设置小时 */
    tm_info.tm_hour = cp56time->hours;
    
    /* 设置分钟 */
    tm_info.tm_min = cp56time->minutes;
    
    /* 设置秒 */
    tm_info.tm_sec = cp56time->milliseconds / 1000;
    
    /* 转换为系统时间 */
    *system_time = mktime(&tm_info);
    if (*system_time == -1) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 获取当前CP56Time2a时间戳
 * @details 获取当前系统时间并转换为CP56Time2a格式。
 *          用于生成当前时间的时间戳，常用于协议数据包。
 * 
 * @param cp56time CP56Time2a时间戳输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 获取成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 系统时间无效
 * 
 * @note 使用time()获取当前系统时间
 * @warning 系统时间获取失败时返回错误
 * 
 * @see system_time_to_cp56time2a
 * @see time
 * @see validate_cp56time2a
 */
protocol_error_t get_current_cp56time2a(cp56time2a_t* cp56time) {
    if (cp56time == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    time_t current_time = time(NULL);
    if (current_time == -1) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    return system_time_to_cp56time2a(current_time, cp56time);
}

/**
 * @brief 检查CP56Time2a时间戳是否有效
 * @details 检查CP56Time2a时间戳是否有效。
 *          用于验证时间戳的有效性，不返回详细错误信息。
 * 
 * @param cp56time CP56Time2a时间戳，不能为NULL
 * @return 检查结果
 *         - 1: 时间戳有效
 *         - 0: 时间戳无效或空指针
 * 
 * @note 此函数是线程安全的
 * @warning 空指针时返回0
 * 
 * @see validate_cp56time2a
 * @see compare_cp56time2a
 */
int is_cp56time2a_valid(const cp56time2a_t* cp56time) {
    if (cp56time == NULL) {
        return 0;
    }
    
    return (validate_cp56time2a(cp56time) == PROTOCOL_SUCCESS);
}

/**
 * @brief 比较两个CP56Time2a时间戳
 * @details 比较两个CP56Time2a时间戳的大小关系。
 *          按照年月日时分秒毫秒的顺序进行比较。
 * 
 * @param time1 第一个时间戳，不能为NULL
 * @param time2 第二个时间戳，不能为NULL
 * @return 比较结果
 *         - -1: time1 < time2 或 空指针错误
 *         - 0: time1 == time2
 *         - 1: time1 > time2
 * 
 * @note 比较顺序：年->月->日->时->分->秒->毫秒
 * @warning 空指针时返回-1
 * 
 * @see is_cp56time2a_valid
 * @see cp56time2a_diff_ms
 */
int compare_cp56time2a(const cp56time2a_t* time1, const cp56time2a_t* time2) {
    if (time1 == NULL || time2 == NULL) {
        return -1;
    }
    
    /* 比较年份 */
    if (time1->year != time2->year) {
        return (time1->year < time2->year) ? -1 : 1;
    }
    
    /* 比较月份 */
    if (time1->month != time2->month) {
        return (time1->month < time2->month) ? -1 : 1;
    }
    
    /* 比较日期 */
    if (time1->day_of_month != time2->day_of_month) {
        return (time1->day_of_month < time2->day_of_month) ? -1 : 1;
    }
    
    /* 比较小时 */
    if (time1->hours != time2->hours) {
        return (time1->hours < time2->hours) ? -1 : 1;
    }
    
    /* 比较分钟 */
    if (time1->minutes != time2->minutes) {
        return (time1->minutes < time2->minutes) ? -1 : 1;
    }
    
    /* 比较毫秒 */
    if (time1->milliseconds != time2->milliseconds) {
        return (time1->milliseconds < time2->milliseconds) ? -1 : 1;
    }
    
    /* 毫秒比较已完成 */
    
    return 0; /* 相等 */
}

/**
 * @brief 计算两个CP56Time2a时间戳的毫秒差值
 * @details 计算两个CP56Time2a时间戳之间的毫秒差值。
 *          用于时间间隔计算和超时检测。
 * 
 * @param time1 第一个时间戳，不能为NULL
 * @param time2 第二个时间戳，不能为NULL
 * @param diff_ms 毫秒差值输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 计算成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 *         - PROTOCOL_ERROR_DATA_CONVERSION_FAILED: 时间转换失败
 * 
 * @note 差值 = time1 - time2（毫秒）
 * @warning 时间戳必须是有效的CP56Time2a格式
 * 
 * @see compare_cp56time2a
 * @see cp56time2a_to_system_time
 * @see is_cp56time2a_valid
 */
protocol_error_t cp56time2a_diff_ms(const cp56time2a_t* time1, const cp56time2a_t* time2, int32_t* diff_ms) {
    if (time1 == NULL || time2 == NULL || diff_ms == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证时间戳 */
    if (!is_cp56time2a_valid(time1) || !is_cp56time2a_valid(time2)) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 转换为系统时间计算差值 */
    time_t sys_time1, sys_time2;
    protocol_error_t result1 = cp56time2a_to_system_time(time1, &sys_time1);
    protocol_error_t result2 = cp56time2a_to_system_time(time2, &sys_time2);
    
    if (result1 != PROTOCOL_SUCCESS || result2 != PROTOCOL_SUCCESS) {
        return PROTOCOL_ERROR_DATA_CONVERSION_FAILED;
    }
    
    /* 计算秒差值 */
    int64_t diff_seconds = (int64_t)sys_time1 - (int64_t)sys_time2;
    
    /* 转换为毫秒差值 */
    *diff_ms = (int32_t)(diff_seconds * 1000);
    
    /* 加上毫秒差值 */
    *diff_ms += (int32_t)time1->milliseconds - (int32_t)time2->milliseconds;
    
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 为CP56Time2a时间戳添加毫秒
 * @details 为CP56Time2a时间戳添加指定的毫秒数。
 *          用于时间偏移计算和超时设置。
 * 
 * @param cp56time CP56Time2a时间戳，不能为NULL
 * @param ms 要添加的毫秒数（可以为负数）
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 添加成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 *         - PROTOCOL_ERROR_DATA_CONVERSION_FAILED: 时间转换失败
 * 
 * @note 支持负数毫秒（时间回退）
 * @warning 时间戳必须是有效的CP56Time2a格式
 * 
 * @see cp56time2a_diff_ms
 * @see cp56time2a_to_system_time
 * @see system_time_to_cp56time2a
 */
protocol_error_t cp56time2a_add_ms(cp56time2a_t* cp56time, int32_t ms) {
    if (cp56time == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证时间戳 */
    if (!is_cp56time2a_valid(cp56time)) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 转换为系统时间 */
    time_t sys_time;
    protocol_error_t result = cp56time2a_to_system_time(cp56time, &sys_time);
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    /* 添加毫秒 */
    int64_t total_ms = (int64_t)sys_time * 1000 + cp56time->milliseconds + ms;
    
    /* 转换回系统时间 */
    sys_time = (time_t)(total_ms / 1000);
    cp56time->milliseconds = (uint16_t)(total_ms % 1000);
    
    /* 转换回CP56Time2a */
    return system_time_to_cp56time2a(sys_time, cp56time);
}

/**
 * @brief CP56Time2a时间戳转字符串
 * @details 将CP56Time2a时间戳转换为指定格式的字符串。
 *          支持标准strftime格式和自定义毫秒格式。
 * 
 * @param cp56time CP56Time2a时间戳，不能为NULL
 * @param buffer 输出字符串缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param format 时间格式字符串，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 支持%f格式符表示毫秒
 * @warning 缓冲区大小必须足够容纳格式化后的字符串
 * 
 * @see string_to_cp56time2a
 * @see strftime
 * @see localtime
 */
protocol_error_t cp56time2a_to_string(const cp56time2a_t* cp56time, char* buffer, size_t buffer_size, const char* format) {
    if (cp56time == NULL || buffer == NULL || format == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    if (buffer_size == 0) {
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    /* 验证时间戳 */
    if (!is_cp56time2a_valid(cp56time)) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 转换为系统时间 */
    time_t sys_time;
    protocol_error_t result = cp56time2a_to_system_time(cp56time, &sys_time);
    if (result != PROTOCOL_SUCCESS) {
        return result;
    }
    
    struct tm* tm_info = localtime(&sys_time);
    if (tm_info == NULL) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 格式化时间字符串 */
    size_t len = strftime(buffer, buffer_size, format, tm_info);
    if (len == 0) {
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    /* 如果需要包含毫秒，追加毫秒信息 */
    if (strstr(format, "%f") != NULL) {
        char ms_str[8];
        snprintf(ms_str, sizeof(ms_str), ".%03d", cp56time->milliseconds);
        
        if (len + strlen(ms_str) < buffer_size) {
            strcat(buffer, ms_str);
        }
    }
    
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字符串转CP56Time2a时间戳
 * @details 将指定格式的时间字符串转换为CP56Time2a时间戳。
 *          支持标准strptime格式和自定义毫秒解析。
 * 
 * @param time_str 时间字符串，不能为NULL
 * @param format 时间格式字符串，不能为NULL
 * @param cp56time CP56Time2a时间戳输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 支持.xxx格式的毫秒解析
 * @warning 时间字符串必须符合指定格式
 * 
 * @see cp56time2a_to_string
 * @see strptime
 * @see mktime
 */
protocol_error_t string_to_cp56time2a(const char* time_str, const char* format, cp56time2a_t* cp56time) {
    if (time_str == NULL || format == NULL || cp56time == NULL) {
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    struct tm tm_info;
    memset(&tm_info, 0, sizeof(struct tm));
    
    /* 解析时间字符串 */
    char* result = strptime(time_str, format, &tm_info);
    if (result == NULL) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 转换为系统时间 */
    time_t sys_time = mktime(&tm_info);
    if (sys_time == -1) {
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    /* 转换为CP56Time2a */
    protocol_error_t error = system_time_to_cp56time2a(sys_time, cp56time);
    if (error != PROTOCOL_SUCCESS) {
        return error;
    }
    
    /* 解析毫秒（如果存在） */
    const char* ms_pos = strstr(time_str, ".");
    if (ms_pos != NULL) {
        int ms = 0;
        if (sscanf(ms_pos + 1, "%3d", &ms) == 1) {
            cp56time->milliseconds = (uint16_t)ms;
        }
    }
    
    return PROTOCOL_SUCCESS;
}

/* ==================== 时间格式化函数实现 ==================== */

/**
 * @brief 获取默认时间格式
 * @details 获取默认的时间格式字符串。
 *          用于时间字符串的格式化和解析。
 * 
 * @return 默认时间格式字符串
 * 
 * @note 格式为"%Y-%m-%d %H:%M:%S"
 * @warning 返回的字符串是常量，不应修改
 * 
 * @see get_iso8601_time_format
 * @see cp56time2a_to_string
 * @see string_to_cp56time2a
 */
const char* get_default_time_format(void) {
    return "%Y-%m-%d %H:%M:%S";
}

/**
 * @brief 获取ISO8601时间格式
 * @details 获取ISO8601标准的时间格式字符串。
 *          用于时间字符串的格式化和解析。
 * 
 * @return ISO8601时间格式字符串
 * 
 * @note 格式为"%Y-%m-%dT%H:%M:%S"
 * @warning 返回的字符串是常量，不应修改
 * 
 * @see get_default_time_format
 * @see cp56time2a_to_string
 * @see string_to_cp56time2a
 */
const char* get_iso8601_time_format(void) {
    return "%Y-%m-%dT%H:%M:%S";
}

/**
 * @brief 获取紧凑时间格式
 * @details 获取紧凑的时间格式字符串（无分隔符）。
 *          用于时间字符串的格式化和解析。
 * 
 * @return 紧凑时间格式字符串
 * 
 * @note 格式为"%Y%m%d%H%M%S"
 * @warning 返回的字符串是常量，不应修改
 * 
 * @see get_default_time_format
 * @see get_iso8601_time_format
 * @see cp56time2a_to_string
 */
const char* get_compact_time_format(void) {
    return "%Y%m%d%H%M%S";
}

/* ==================== 时间验证函数实现 ==================== */

/**
 * @brief 检查年份是否有效
 * @details 检查CP56Time2a年份是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param year 年份值
 * @return 检查结果
 *         - 1: 年份有效
 *         - 0: 年份无效
 * 
 * @note 年份范围：0-255（相对于2000年）
 * @warning 此函数不检查闰年
 * 
 * @see is_month_valid
 * @see is_day_valid
 * @see validate_cp56time2a
 */
int is_year_valid(uint8_t year) {
    return (year <= CP56TIME2A_MAX_YEAR);
}

/**
 * @brief 检查月份是否有效
 * @details 检查CP56Time2a月份是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param month 月份值
 * @return 检查结果
 *         - 1: 月份有效
 *         - 0: 月份无效
 * 
 * @note 月份范围：1-12
 * @warning 此函数不检查月份天数
 * 
 * @see is_year_valid
 * @see is_day_valid
 * @see validate_cp56time2a
 */
int is_month_valid(uint8_t month) {
    return (month >= 1 && month <= CP56TIME2A_MAX_MONTH);
}

/**
 * @brief 检查日期是否有效
 * @details 检查CP56Time2a日期是否在有效范围内，包含闰年检查。
 *          用于时间戳验证和错误检查。
 * 
 * @param year 年份值
 * @param month 月份值
 * @param day 日期值
 * @return 检查结果
 *         - 1: 日期有效
 *         - 0: 日期无效
 * 
 * @note 日期范围：1-31（根据月份和闰年调整）
 * @warning 自动处理闰年和不同月份的天数
 * 
 * @see is_year_valid
 * @see is_month_valid
 * @see validate_cp56time2a
 */
int is_day_valid(uint8_t year, uint8_t month, uint8_t day) {
    if (!is_year_valid(year) || !is_month_valid(month)) {
        return 0;
    }
    
    if (day < 1 || day > CP56TIME2A_MAX_DAY) {
        return 0;
    }
    
    /* 检查月份天数 */
    int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    /* 闰年检查 */
    int actual_year = year + CP56TIME2A_YEAR_BASE;
    if (actual_year % 4 == 0 && (actual_year % 100 != 0 || actual_year % 400 == 0)) {
        days_in_month[1] = 29; /* 2月29天 */
    }
    
    return (day <= days_in_month[month - 1]);
}

/**
 * @brief 检查小时是否有效
 * @details 检查CP56Time2a小时是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param hour 小时值
 * @return 检查结果
 *         - 1: 小时有效
 *         - 0: 小时无效
 * 
 * @note 小时范围：0-23
 * @warning 使用24小时制
 * 
 * @see is_minute_valid
 * @see is_second_valid
 * @see validate_cp56time2a
 */
int is_hour_valid(uint8_t hour) {
    return (hour <= CP56TIME2A_MAX_HOUR);
}

/**
 * @brief 检查分钟是否有效
 * @details 检查CP56Time2a分钟是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param minute 分钟值
 * @return 检查结果
 *         - 1: 分钟有效
 *         - 0: 分钟无效
 * 
 * @note 分钟范围：0-59
 * @warning 此函数不处理闰秒
 * 
 * @see is_hour_valid
 * @see is_second_valid
 * @see validate_cp56time2a
 */
int is_minute_valid(uint8_t minute) {
    return (minute <= CP56TIME2A_MAX_MINUTE);
}

/**
 * @brief 检查秒是否有效
 * @details 检查CP56Time2a秒是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param second 秒值
 * @return 检查结果
 *         - 1: 秒有效
 *         - 0: 秒无效
 * 
 * @note 秒范围：0-59
 * @warning 此函数不处理闰秒
 * 
 * @see is_minute_valid
 * @see is_millisecond_valid
 * @see validate_cp56time2a
 */
int is_second_valid(uint8_t second) {
    return (second <= CP56TIME2A_MAX_SECOND);
}

/**
 * @brief 检查毫秒是否有效
 * @details 检查CP56Time2a毫秒是否在有效范围内。
 *          用于时间戳验证和错误检查。
 * 
 * @param millisecond 毫秒值
 * @return 检查结果
 *         - 1: 毫秒有效
 *         - 0: 毫秒无效
 * 
 * @note 毫秒范围：0-999
 * @warning 此函数不处理微秒或纳秒
 * 
 * @see is_second_valid
 * @see validate_cp56time2a
 * @see cp56time2a_add_ms
 */
int is_millisecond_valid(uint16_t millisecond) {
    return (millisecond <= CP56TIME2A_MAX_MILLISECOND);
}
/**
 * @file time_handling.c
 * @brief 时间戳处理实现
 * @details 本文件实现了104协议中CP56Time2a时间戳的解析和构建功能，
 *          包括时间戳的编码、解码、验证等操作。
 * 
 * @author zyb
 * @date 2025-10-03
 * @version 1.0
 * 
 * @note CP56Time2a时间戳格式严格按照IEC 60870-5-104协议规范
 * @warning 时间戳的年份基准为2000年，范围0-99表示2000-2099
 * 
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

